package jcer.core;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;

public class ConnectionReadHandler extends BaseEventHandler {

	ConnectionReadHandler(EventDriver driver) {
		super(driver);
	}

	@Override
	public void execute(Event event) throws Exception {
		Connection conn = event.conn;

		while (true) {
			int len = conn.read();

			// if not read enogh bytes,wait for the next read event
			if (len == 0) {
				return;
			}

			// if read header complated,then set limit for the body len
			if (conn.readBuf.remaining() == 0
					&& conn.state == Connection.State.READ_HEADER) {
				conn.readBuf.position(0);
				conn.packet = new Packet();
				conn.packet.unpackHeader(conn.readBuf);
				conn.readBuf.position(0);

				// if the buffer is not enogh ,then allocate more buffer
				if (conn.readBuf.capacity() < conn.packet.bodyLen) {
					conn.readBuf = ByteBuffer.allocate(conn.packet.bodyLen
							+ Packet.getHeaderLen());
				}

				// set new limit = body length
				conn.readBuf.limit(conn.packet.bodyLen);
				// update state
				conn.state = Connection.State.READ_BODY;
				continue;
			}

			// has readed all bytes
			if (conn.readBuf.remaining() == 0) {
				// copy bytes to packet body
				conn.readBuf.position(0);
				conn.packet.unpackBody(conn.readBuf);

				// update state
				conn.state = Connection.State.TASK_EXECUTE;

				Event executeEvent = new Event();
				executeEvent.type = Event.Type.TASK_EXECUTE;
				executeEvent.conn = conn;
				conn.driver.addEvent(executeEvent);
			} else {
				// go on to wait read
				conn.socket.register(conn.selector, SelectionKey.OP_READ, conn);
			}

			break;
		}

	}

	@Override
	public void init() {
	}

}
